﻿using System;
using Castle.Windsor;
using Framework.Common.Configs;
using Framework.Common;
using Castle.Windsor.Configuration.Interpreters;
using System.Collections;

namespace Framework.Castle.Windsor
{
    /// <summary>
    /// castle windsor container helper
    /// </summary>
    public class ContainerHelper
    {
        /// <summary>
        /// IWindsorContainer
        /// </summary>
        static IWindsorContainer _container;
        /// <summary>
        /// default container
        /// </summary>
        public static IWindsorContainer Container
        {
            get
            {
                if (_container == null)
                {
                    InitContainer();
                }
                return _container;
            }
        }
        /// <summary>
        /// init container by default config
        /// the config root path is framework.common.config.CustomConfigRoot
        /// </summary>
        private static void InitContainer()
        {
            lock (typeof(ContainerHelper))
            {
                if (_container == null)
                {
                    string fullPath = CustomConfigRoot.ConfigRootPath + "Castle.Windsor.config";
                    if (FileHelper.FileExists(fullPath))
                    {
                        _container = new WindsorContainer(fullPath);
                        FileHelper.WatchFile(fullPath, (a, b) => _container = null);
                    }
                    else
                    {
                        _container = new WindsorContainer();
                    }
                }
            }
        }
        #region resolve

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Resolve<T>()
        {
            return Container.Resolve<T>();
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static T Resolve<T>(IDictionary arguments)
        {
            return Container.Resolve<T>(arguments);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="argumentsAsAnonymousType"></param>
        /// <returns></returns>
        public static T Resolve<T>(object argumentsAsAnonymousType)
        {
            return Container.Resolve<T>(argumentsAsAnonymousType);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T Resolve<T>(string key)
        {
            return Container.Resolve<T>(key);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public static object Resolve(Type service)
        {
            return Container.Resolve(service);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static T Resolve<T>(string key, IDictionary arguments)
        {
            return Container.Resolve<T>(key, arguments);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="argumentsAsAnonymousType"></param>
        /// <returns></returns>
        public static T Resolve<T>(string key, object argumentsAsAnonymousType)
        {
            return Container.Resolve<T>(key, argumentsAsAnonymousType);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="key"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        public static object Resolve(string key, Type service)
        {
            return Container.Resolve(key, service);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="service"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static object Resolve(Type service, IDictionary arguments)
        {
            return Container.Resolve(service, arguments);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="service"></param>
        /// <param name="argumentsAsAnonymousType"></param>
        /// <returns></returns>
        public static object Resolve(Type service, object argumentsAsAnonymousType)
        {
            return Container.Resolve(service, argumentsAsAnonymousType);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="key"></param>
        /// <param name="service"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static object Resolve(string key, Type service, IDictionary arguments)
        {
            return Container.Resolve(key, service, arguments);
        }

        /// <summary>
        /// Resolve
        /// </summary>
        /// <param name="key"></param>
        /// <param name="service"></param>
        /// <param name="argumentsAsAnonymousType"></param>
        /// <returns></returns>
        public static object Resolve(string key, Type service, object argumentsAsAnonymousType)
        {
            return Container.Resolve(key, service, argumentsAsAnonymousType);
        }

        /// <summary>
        /// ResolveAll
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T[] ResolveAll<T>()
        {
            return Container.ResolveAll<T>();
        }

        /// <summary>
        /// ResolveAll
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="arguments"></param>
        /// <returns></returns>
        public static T[] ResolveAll<T>(IDictionary arguments)
        {
            return Container.ResolveAll<T>(arguments);
        }

        /// <summary>
        /// ResolveAll
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="argumentsAsAnonymousType"></param>
        /// <returns></returns>
        public static T[] ResolveAll<T>(object argumentsAsAnonymousType)
        {
            return Container.ResolveAll<T>(argumentsAsAnonymousType);
        }
        #endregion
    }
}
